const path = require('path');
const fs = require('fs');
const admZip = require('adm-zip');
const { exec } = require('child_process');

const getVersion = require('./commit');
const { log, error } = require('./log');

start();

async function nodeExecFile(command) {
  return new Promise((resolve, reject) => {
    const child = exec(command, { maxBuffer: 10240 * 1024 });

    child.on('message', (msg) => {
      log({ state: true, msg: msg });
    });
    child.on('close', (code, msg) => {
      log('children process 进程关闭', code, msg);
      resolve(code);
    });

    child.on('error', err => {
      log('children process error.');
      log(err.message);
    });

    child.stderr.on('data', data => {
      log(data.toString());
    });

    child.stdout.on('data', data => {
      log(data.toString());
    });
  })
}

function getTemplatePath() {
  var myArgs = process.argv.slice(2);
  const templatePath = myArgs[0];
  return templatePath;
}

function requireJSON(filePath) {
  try {
    return JSON.parse(fs.readFileSync(filePath, 'utf8'));
  } catch (error) {
    log(`获取 ${filePath} 出错，错误信息：${error}`);
    return {};
  }
}

function getEnvPlugin(environment, rootPath, pluginFilePath) {
  switch (environment) {
    case "production":
      pluginFilePath = path.join(rootPath, './plugin.prod.json')
      break;
    case "uat":
      pluginFilePath = path.join(rootPath, './plugin.uat.json')
      break;
    case "gamma":
      pluginFilePath = path.join(rootPath, './plugin.gamma.json')
      break;
    default : break;
  }
}

function getAppId(currentpluginJson, flag) {
  // 判断是否有appId这个字段
  if ('appId' in currentpluginJson) {
    if ((process.argv.slice(7)[0] && process.argv.slice(7)[0] != 'all' && process.argv.slice(7)[0] != 'null') || (process.argv.slice(3)[0] != 'all' && process.argv.slice(3)[0] != 'null')) {
      currentpluginJson.appId = process.argv.slice(7)[0] || process.argv.slice(3)[0];
    } else {
      if (process.argv.slice(3)[0] == 'null' && (!process.argv.slice(7)[0] || process.argv.slice(7)[0] == 'null') && !currentpluginJson.appId) {
        log("错误信息：plugin.json文件中appId值为空")
        flag = false
      }
    }
  } else {
    log("错误信息：plugin.json文件中不存在appId")
    flag = false
  }
}

function getIndexUrl(currentpluginJson, flag) {
  let newIndexUrl = ""
  if ('indexURL' in currentpluginJson) {
    if (currentpluginJson.indexURL.match(/h5:\/\//)) {
      newIndexUrl = currentpluginJson.indexURL.replace(/h5:\/\/([^/])*/, `h5://${currentpluginJson.appId}`);
    } else if (currentpluginJson.indexURL === '') {
      log('indexURL为空，将使用默认值');
      newIndexUrl = `h5://${currentpluginJson.appId}/html/index.html`;
    } else {
      log('indexURL不符合规则，将使用默认值');
      newIndexUrl = `h5://${currentpluginJson.appId}/html/index.html`;
    }
  } else {
    log("错误信息：plugin.json文件中不存在indexURL")
    flag = false
  }
  if (process.argv.slice(3)[0] != 'all' && process.argv.slice(3)[0] != 'null' || (process.argv.slice(7)[0] != 'all' && process.argv.slice(7)[0] != 'null')) {
    currentpluginJson.indexURL = newIndexUrl
  }
}

function getPluginConfig(rootPath, environment) {
  let flag = true
  const reletivePath = path.join(process.argv.slice(5)[0])
  let gitPath = path.resolve(process.cwd())
  gitPath = gitPath.replace(reletivePath, '');
  let pluginFilePath = path.join(rootPath, './.wecode/plugin.json')

  if (!fs.existsSync(pluginFilePath)) {
    getEnvPlugin(environment, rootPath, pluginFilePath);
    if (!fs.existsSync(pluginFilePath)) {
      pluginFilePath = path.join(rootPath, './plugin.json')
    }
  }
  log('pluginFilePath-----', pluginFilePath)
  if (fs.existsSync(pluginFilePath)) {
    let currentpluginJson = requireJSON(pluginFilePath);
    getAppId(currentpluginJson, flag);
    // 判断是否能获取到commitId
    log('-------- get gitPath', process.cwd(), gitPath);
    if (getVersion.getVersion(gitPath)) {
      currentpluginJson.commitId = getVersion.getVersion(gitPath)
      log(currentpluginJson, 'currentpluginJson---')
    } else {
      if (process.argv.slice(8)[0] !== 'init') {
        log("错误信息：无法获取commitId,请检查是否误删除了根目录下的.git文件夹")
        flag = false
      }
    }

    getIndexUrl(currentpluginJson, flag);
    fs.writeFile(pluginFilePath, JSON.stringify(currentpluginJson), function (err) {
      if (err) {
        return error(err);
      }
      fs.readFile(pluginFilePath, function (err, data) {
        if (err) {
          return error(err);
        }
        log("plugin.json" + data.toString());
      });
    });
  }
  return flag
}
// 处理获取wecode.json文件路径
function getWeCodePath (value) {
  return fs.existsSync(value)
}
function getWeCodeConfig(rootPath) {
  let filePath = '';
  // 1、历史版本约定地址 wecode.json 地址
  const wecodeFilePath = path.join(rootPath, './wecode.json');
  const wecodeJson = {};

  if (getWeCodePath(wecodeFilePath)) {
    filePath = wecodeFilePath;
    let currentWecodeJson = requireJSON(wecodeFilePath);
    Object.assign(wecodeJson, currentWecodeJson);
  }
  // 2、新版约定的配置在 src/app.json 中
  const appFilePath = path.join(rootPath, 'src/app.json');
  if (getWeCodePath(appFilePath)) {
    filePath = appFilePath;
    const appJson = requireJSON(appFilePath);
    if (appJson && appJson.runtime) { // 合并 wecodeJson 配置
      Object.assign(wecodeJson, appJson.runtime);
    }
  }
  return wecodeJson;
}

// 检测文件或者文件夹存在
function fsExistsSync(pathDir) {
  try {
    fs.accessSync(pathDir, fs.F_OK);
  } catch (e) {
    return false;
  }
  return true;
}

async function start() {
  log('----- get process.argv', process.argv);
  const environment = process.env.WECODE_ENV || process.argv.slice(4)[0];
  const templatePath = getTemplatePath();
  if (!templatePath) {
    log(`We码打包失败，需要指定We码的路径。例如：build.js ./template/name`);
    return;
  }
  const templateAllPath = path.join(process.cwd(), templatePath);
  const pluginConfig = getPluginConfig(templatePath, environment)
  if (pluginConfig) {
    const wecodeConfig = getWeCodeConfig(templatePath);
    log(wecodeConfig, "wecodeConfig")
    const { templateName, templateVersion } = wecodeConfig;
    const runtimePath = path.join(process.cwd(), `./runtime`);
    log('获取依赖的类型与版本', templateName, templateVersion);

    const buildScriptPath = path.join(runtimePath, `1.0.0/scripts/runbuild.js`);

    // 执行打包逻辑
    await nodeExecFile(`node ${buildScriptPath} --templatePath=${templateAllPath} --environment=${environment}`);

    // 执行命令时进行压缩
    const compileFile = path.join(process.cwd(), `./build/apps/local/0`);
    const distFile = path.join(process.cwd(), `./build/apps/local/dist.zip`);
    const zip = new admZip();
    if(process.argv.slice(6)[0] === 'command' && fs.existsSync(compileFile)) {
      log('-------- command')
      zip.addLocalFolder(compileFile);
      zip.writeZip(distFile);
    }

    // 执行命令时进行压缩
    const compileMapFile = path.join(process.cwd(), `./build/apps/local/1`);
    const distMapFile = path.join(process.cwd(), `./build/apps/local/dist_map.zip`);
    const zipMap = new admZip();
    if(process.argv.slice(6)[0] === 'command' && fs.existsSync(compileMapFile)) {
      log('-------- command map')
      zipMap.addLocalFolder(compileMapFile);
      zipMap.writeZip(distMapFile);
    }
  } else {
    log("打包失败---------")
  }
}